<?php
require_once 'application/models/AbstractModel.php';
require_once 'application/models/Exercice.php';
require_once 'application/models/Serie.php';

class Batterie extends AbstractModel
{
	public static $_VISIBILITY_PUBLIC_READ = 0;
	public static $_VISIBILITY_PUBLIC_WRITE = 1;
	public static $_VISIBILITY_PRIVATE = 2;
	
	protected $_name = 'Batterie';

    protected $_dependentTables = array('Exercice', 'Serie');

    private static $minQuestion = 1;
	private static $minPage = 1;
	private static $minSerie = 0;
    
    function __construct() {
        parent::__construct();
    	$this->_fieldsToDisplay = array('id', 'description', 'nom', 'visibility_id', 'batterie_type_id', 'numero_enabled', 'modifiable', 'dictee_enabled', 'default_tempo', 'image_mandatory', 'sound_mandatory', 'question_per_page', 'page_per_serie');
    }
   
	public function getArrayFromRow($row) {
        $result = parent::getArrayFromRow($row);
		// check if the user is logged
		$isOwner = '0'; //false
		$auth = Zend_Auth::getInstance();
        if ($auth->hasIdentity()) {
			// user is logged
			$user = $auth->getIdentity();
			if ($user->id == $row['owner_id']) {
				$isOwner = '1'; //true
			}
		}
		$result['is_owner'] = $isOwner;
     	return $result;
	}
    
    /**
     * 
     * Build BAtterie object and fetch its exercices.
     * If $buildFullPath is true, the exercices will follow the following array pattern :
     * 		batterie["exercices"]["series"][$e->serie]["page"][$e->page]["question"][$e->question_numero] = exercices...
     * else :
     * 		batterie["exercices"] = exercices...
     */
    function getObjectFromRow($row, $buildFullPath) {
    	$object = $this->getArrayFromRow($row);
    	
    	// get series
	    $tableS = new Serie();
		
	    $sRows = $row->findDependentRowset('Serie', 'Serie');
	    
	    $sList = array();
	    foreach ($sRows as $sRow) {
	    	$objS = $tableS->getArrayFromRow($sRow);
	    	$sList[$objS['serie_number']] = $objS;
	    }
	    $object['series'] = $sList;
    	
	    // get exercices
	    $exercice = new Exercice();
	    
		$select = $this->select()->order('id ASC');
	    $exerciceRows = $row->findDependentRowset('Exercice', 'Batterie', $select);
	    $exerciceList = null;
	    
	    $metaData = $this->initMetaData();
	    
	    foreach ($exerciceRows as $e) {
	    
	    	$currentExercice = $exercice->getArrayFromRow($e);
    		$currentExercice = array_merge($currentExercice, array(
    			'serie' => $metaData['currentSerie'],
    			'page' => $metaData['currentPage'],
    			'question_numero' => $metaData['currentQuestion']
    		));
	    	if ($buildFullPath) {
		    	$exerciceList["series"][$metaData['currentSerie']]["page"][$metaData['currentPage']]["question"][$metaData['currentQuestion']] = $currentExercice;
	    	}else{
		    	$exerciceList[] = $currentExercice;
	    	}
	    	
	    	$metaData = $this->incrementMetaData($metaData, $row->question_per_page, $row->page_per_serie);
	    }
	    $object['exercices'] = $exerciceList;
    		    
	    return $object;
    }
    
    function initMetaData() {
    	return array(
			'currentQuestion' => self::$minQuestion,
			'currentPage' => self::$minPage,
			'currentSerie' => self::$minSerie
    	);
    }
    
    function getLastMetaData($row) {
    	$tableE = new Exercice();
    	$select = $tableE->select();
		$select->from($tableE,
		              array('COUNT(id) as count', 'id'))
		       ->where('batterie_id = ?', $row->id);
		 
		$countRows = $tableE->fetchAll($select);
		$count = $countRows[0]->count;
		
    	return array(
			'question_numero' => (($count - 1) % $row->question_per_page) + self::$minQuestion,
			'page' => (floor(($count - 1) / ($row->question_per_page)) % $row->page_per_serie) + self::$minPage,
			'serie' => floor(($count - 1) / ($row->question_per_page * $row->page_per_serie)) + self::$minSerie
    	);
    }
   
    function incrementMetaData($metaData, $maxQuestion, $maxPage) {
		$metaData['currentQuestion']++;
    	
    	// increment page if needed
		if ($maxQuestion > 0 && $metaData['currentQuestion'] > $maxQuestion) {
			$metaData['currentQuestion'] = self::$minQuestion;
			$metaData['currentPage']++;
		}
		// increment serie
		if ($maxPage > 0 && $metaData['currentPage'] > $maxPage) {
			$metaData['currentPage'] = self::$minPage;
			$metaData['currentSerie']++;
		}
		
		return $metaData;
    }
    
    
    
    
    /**
     * 
     * Return a list of batteries. 
     * - If "tid" param is set, all batteries with this type id 
     *   are returned, with their exezrcices
     * - Else, all batteries are returned, without thier exercices
     */
    public static function listBatteries($tid, $ids, $writable, $user)
    {
    	if (isset($tid) || isset($ids)) {
			return self::listByParams(array('tid' => $tid, 'ids' => $ids), $user);
		}else {
			return self::listAll($writable, $user);
		}
    }
    
    public static function listByParams($params, $user) {
		// get Batterie from type id
	    $batterie = new Batterie();
	    
	    // Where clauses
	    $where = array();
		if (isset($params['tid'])) {
			// by type
	   		$where[] = $batterie->getAdapter()->quoteInto('batterie_type_id = ?', $params['tid']);
		}
		if (isset($params['ids'])) {
			// by id
			$where[] = $batterie->getAdapter()->quoteInto('id IN (?)', explode(',', $params['ids']));
		}
		
		$wherePublicReading = $batterie->getAdapter()->quoteInto('(visibility_id < ?)',Batterie::$_VISIBILITY_PRIVATE);
		$whereOwner = $batterie->getAdapter()->quoteInto('(owner_id = ?)', $user->id);
		
		$where[] = $wherePublicReading.' OR '.$whereOwner;
	    $batterieRows = $batterie->fetchAll($where);
    	
	    //check asnwer : 404 if not found
	    if (isset($batterieRows[0])) {
	    	$result = array();
	    	$result["batteries"] = array();
	    	
			for ($i = 0; $i < count($batterieRows); $i++) {
	    		$bat = $batterie->getObjectFromRow($batterieRows[$i], true);
				$id = $bat["id"];
			    $result["batteries"][$id] = $bat;
	    	}
			// render
			return $result;
	    }else{
	    	return false;
	    }
    }
    
    public static function listAll($writable,$user) {
	    $batterie = new Batterie();
	    
	    if ($writable) {
			$wherePublicWriting = $batterie->getAdapter()->quoteInto('(visibility_id = ?)',Batterie::$_VISIBILITY_PUBLIC_WRITE);
			$whereOwner = $batterie->getAdapter()->quoteInto('(owner_id = ?)', $user->id);
			
			$batterieRows = $batterie->fetchAll($wherePublicWriting.' OR '.$whereOwner);
	    }else{
			$batterieRows = $batterie->fetchAll();
	    }
	    
    	$result = array();
    	$result["batteries"] = array();
    	
	    if (isset($batterieRows[0])) {
	    	for ($i = 0; $i < count($batterieRows); $i++) {
	    		$bat = $batterie->getArrayFromRow($batterieRows[$i]);
				$id = $bat["id"];
			    $result["batteries"][$id] = $bat;
				
				// get exercices
			    $exercice = new Exercice();
				$where = $exercice->getAdapter()->quoteInto('batterie_id = ?', $id);
			    $exerciceRows = $exercice->fetchAll($where);
				
	    	}
	    }
		// render
		return $result;
    }
    
}
    	